package com.mk.ssm.service.impl;

import com.mk.ssm.aop.MethodCache;
import com.mk.ssm.bean.entity.Resource;
import com.mk.ssm.bean.entity.Role;
import com.mk.ssm.mapper.ResourceMapper;
import com.mk.ssm.mapper.RoleMapper;
import com.mk.ssm.service.ResourceService;
import com.mk.ssm.utils.Constants;
import com.mk.ssm.utils.ResultUtil;
import org.apache.shiro.authz.permission.WildcardPermission;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.cache.RedisCache;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>Resource: yankee
 * <p>Date: 17-4-3
 * <p>Version: 1.0
 */
@Service("resourceService")
public class ResourceServiceImpl implements ResourceService {
    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    @Autowired(required = false)
    private ResourceMapper resourceDao;
    @Autowired(required = false)
    private RedisCache cache;
    @Autowired
    private RoleMapper roleDao;

    @Override
    public int createResource(Resource resource) {
        Integer res;
        //判断添加时需要的字段
        if(resource.getName() != null && !"".equals(resource.getName())
                && resource.getType() != null && !"".equals(resource.getType())
                && resource.getUrl() != null && !"".equals(resource.getUrl()) && resource.getParentId() != null
                && resource.getPermission() != null && !"".equals(resource.getPermission())) {
            //判断父节点是否在数据库中存在
            Resource resource1 = resourceDao.findOne(resource.getParentId(), Constants.ABLE_CONFIG.ABLE);
            if(resource1 != null) {
                resource.setParentIds(getParentIds(resource.getParentId()));
                resource.setAble(Constants.ABLE_CONFIG.DEFAULT_ABLE);
                res = resourceDao.createResource(resource);
                return res;
            }
            //传入的父节点在数据库中不存在
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
        }else
            //传入的属性不全
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
        return res;
    }

    @Override
    public int updateResource(Resource resource) {
        Integer res;
        //查找资源是否存在
        Resource resource1 = resourceDao.findOne(resource.getId(), Constants.ABLE_CONFIG.ABLE);
        if(resource1 != null) {
            Resource resource2 = resourceDao.findOne(resource.getParentId(), Constants.ABLE_CONFIG.ABLE);
            //父节点不为空
            if(resource.getParentId() != null){
                if(resource2 != null){
                    //赋值父节点字符串
                    resource.setParentIds(getParentIds(resource.getParentId()));
                    res = resourceDao.updateResource(resource);
                    return res;
                }
                //说明其父节点在数据库中不存在
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
            }else if((resource.getName() == null || "".equals(resource.getName()))
                    && (resource.getUrl() == null || "".equals(resource.getUrl()))
                    && (resource.getType() == null || "".equals(resource.getType()))
                    && (resource.getPermission() == null || "".equals(resource.getPermission()))
                    && (resource.getParentIds() == null || "".equals(resource.getParentIds()))
                    && resource.getAble() == null && resource.getParentId() == null){
                res = ResultUtil.RESULT_CONFIG.RESULT_NUM05;
            }else
                //未传入父节点，修改其他属性
                res = resourceDao.updateResource(resource);
        }else
            //根据传入的资源id查找不到对应的资源信息
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
        return res;
    }

    @Override
    public int deleteResource(Long resourceId) {
        Integer res;
        Resource resource = resourceDao.findOne(resourceId, Constants.ABLE_CONFIG.ABLE);
        List<Role> roleList = roleDao.findAll(Constants.ABLE_CONFIG.ABLE);
        if(resource != null) {
            for (int i = 0; i < roleList.size(); i++) {
                List<Long> resourceIds = roleList.get(i).getResourceIds();
                //遍历查找角色信息，如果角色信息中查找不到，可以删除
                for (int j = 0; j < resourceIds.size(); j++) {
                    if(resource.getId() == resourceIds.get(j)){
                        res = ResultUtil.RESULT_CONFIG.RESULT_NUM02;
                        return res;
                    }
                }
            }
            res = resourceDao.deleteResource(resourceId, Constants.ABLE_CONFIG.UNABLE);
        }else
            res = ResultUtil.RESULT_CONFIG.RESULT_NUM01;
        return res;
    }

    @Override
    @MethodCache(clz = Resource.class)
    public Resource findOne(Long resourceId) {
        return resourceDao.findOne(resourceId, Constants.ABLE_CONFIG.ABLE);
    }

    @Override
    @MethodCache(isCollection = 1, clz = Resource.class)
    public List<Resource> findAll() {
        return resourceDao.findAll(Constants.ABLE_CONFIG.ABLE);
    }

    @Override
    public List<Resource> findByColumns(Resource resource) {
        //处理空指针
        if(resource == null) {
            resource = new Resource();
            resource.setAble(Constants.ABLE_CONFIG.ABLE);
        }else
            resource.setAble(Constants.ABLE_CONFIG.ABLE);
        return resourceDao.findByColumns(resource);
    }


    @Override
    @MethodCache(isCollection = 1, clz = String.class)
    public List<String> findPermissions(List<Long> resourceIds) {
        List<String> permissions = new ArrayList<String>();
        for (Long resourceId : resourceIds) {
            Resource resource = findOne(resourceId);
            if (resource != null && !StringUtils.isEmpty(resource.getPermission())) {
                permissions.add(resource.getPermission());
            }
        }
        return permissions;
    }

    @Override
    @MethodCache(isCollection = 1, clz = Resource.class)
    public List<Resource> findMenus(List<String> permissions) {
        List<Resource> allResources = findAll();
        List<Resource> menus = new ArrayList<Resource>();
        for (Resource resource : allResources) {
            if (resource.isRootNode()) {
                continue;
            }
            if ("menu".equals(resource.getType())) {
                continue;
            }
            if (!hasPermission(permissions, resource)) {
                continue;
            }
            menus.add(resource);
        }
        return menus;
    }

    private boolean hasPermission(List<String> permissions, Resource resource) {
        if (StringUtils.isEmpty(resource.getPermission())) {
            return true;
        }
        for (String permission : permissions) {
            WildcardPermission p1 = new WildcardPermission(permission);
            WildcardPermission p2 = new WildcardPermission(resource.getPermission());
            if (p1.implies(p2) || p2.implies(p1)) {
                return true;
            }
        }
        return false;
    }

    /**
     * 查找父节点
     */
    private String getTotalParent(Long num){
        StringBuilder str = new StringBuilder(num+"/");
        while(true) {
            Resource resource = resourceDao.findOne(num, Constants.ABLE_CONFIG.ABLE);
            num = resource.getParentId();
            str.append(num + "/");
            if(num == Constants.PARENT_CONFIG.TOTAL_PARENTID){
                break;
            }
            getTotalParent(resource.getParentId());
        }
//        System.out.println(str.toString());
        return str.toString();
    }

    /**
     * 查找完所有的父节点后调整字符串中的先后顺序
     * @return
     */
    private String getParentIds(Long parentId){
        String str = getTotalParent(parentId);
        System.out.println("str="+str);
        String [] str1 = str.split("/");
        StringBuilder str2 = new StringBuilder();
        for (int i = str1.length-1; i >= 0 ; i--) {
            str2.append(str1[i] + "/");
        }
        System.out.println(str2.toString());
        return str2.toString();
    }
}
